#include "globals.h"
#include "util.h"

char * copyString(const char * s)
{
    int n;
    char *t;
    if(s==NULL)return NULL;
    n=strlen(s);
    t=(char *)malloc(n+1);
    strcpy(t,s);
    return t;
}

namespace CPP2{
extern int lineno;
TreeNode * newStmtNode(StmtKind kind)
{
	TreeNode * t= (TreeNode *)malloc(sizeof(TreeNode));
	int i;
	for(i=0;i<MAXCHILDREN;++i)t->child[i]=NULL;
	t->sibling=NULL;
	t->nodekind=StmtK;
	t->kind.stmt=kind;
    t->lineno=lineno;
	return t;
}

TreeNode * newExpNode(ExpKind kind)
{
	TreeNode * t=(TreeNode *)malloc(sizeof(TreeNode));
	int i;
	for(i=0;i<MAXCHILDREN;++i)t->child[i]=NULL;
	t->sibling=NULL;
	t->nodekind=ExpK;
	t->kind.exp=kind;
    t->lineno=lineno;
    t->type=Void;
	return t;
}

static char tmp[64];
char * nodeToString(TreeNode *n)
{
	char op='?';
	switch(n->nodekind)
	{
	case StmtK:
		switch(n->kind.stmt)
		{
		case IfK:
			return "if";
		case RepeatK:
			return "repeat";
		case AssignK:
			sprintf(tmp,"assign(%s)",n->attr.name);
			return tmp;
/*		case ReadK:
			sprintf(tmp,"read(%s)",n->attr.name);
			return tmp;
		case WriteK:
			return "write";
*/		case WhileK:
			return "while";
/*		case DoK:
			return "do";
        case ForK:
			return "for";
*/		case ReturnK:
            return "return";
        default:
			return "STMT?";
		}
		break;
	case ExpK:
		switch(n->kind.exp)
		{
		case OpK:
			switch(n->attr.op)
			{
			case EQ:
				op = '=';
				break;
			case LT:
				op = '<';
				break;
			case PLUS:
				op = '+';
				break;
			case MINUS:
				op = '-';
				break;
/*			case TIMES:
				op = '*';
				break;
			case OVER:
				op = '/';
				break;
			case MOD:
				op = '%';
				break;
*/
            case LPAREN:
				op = '(';
				break;
			case RPAREN:
				op = ')';
				break;
			case SEMI:
				op = ';';
				break;
			}
			sprintf(tmp,"op(%c)",op);
			return tmp;
			break;
		case ConstK:
			sprintf(tmp,"const(%d)",n->attr.val);
			return tmp;
			break;
		case IdK:
			sprintf(tmp,"id(%s)",n->attr.name);
			return tmp;
			break;
        case InvokeK:
            switch (n->attr.op) {
            case A:
                return "A";
            case B:
                return "B";
            case C:
                return "C";
            case R:
                return "R";
            default:
                return "Invoke?";
                break;
            }
		default:
			return "EXP?";
		}
		break;
	default:
        return "?";
	}
}
static char prefix[]="                                                                      ...";
void printTree(TreeNode *t,int deep)
{
    int i;
    while(t!=NULL){
        printf("%.*s%s\n",deep,prefix,nodeToString(t));
        for(i=0;i<MAXCHILDREN;++i){
            printTree(t->child[i],deep+2);
        }
        t=t->sibling;
    }
}
}//end namespace CPP2
